var api = require('./footballAPI.js');
var db = require('./db-config.js');
var users = require('./users.js');
var scheduler = require('./cron-job.js');
var xmlUtils = require('./xmlUtils.js');
var sudo = "sudo";

var markedMatches = [];

/**
 * Set of points rules
 */
var rules = [{
    level : 'Group',
    bullseye : 1,
    qualifier : 4,
    qualifierBullseye : 5,
    costToOpen : 0
}, {
    level : 'F',
    pointsToGive : 13,
    bullseye : 5,
    costToOpen : 13
}, {
    level : 'SF',
    pointsToGive : 11,
    bullseye : 4,
    costToOpen : 11
}, {
    level : 'QF',
    pointsToGive : 9,
    bullseye : 3,
    costToOpen : 9
}, {
    level : '1/8',
    pointsToGive : 7,
    bullseye : 2,
    costToOpen : 7
}, {
    level : 'Tournament Bets',
    kingOfAssists : 5,
    kingOfGoals : 5,
    champions : [4, 8, 12, 16]
}];

exports.rules = rules;

/***
 *
 * @param {int} level 0-4
 */
var nextBettingDeadline = function(level) {
    api.nextBettingDeadLine(level, function(result) {
        console.log("Setting next betting deadline");
    });
};

/**
 * Gets all the matches that are being played on this date
 * @param dateObject
 * @return {array} of objects {match_id:<value>}
 */
var getMatchesByDate = function(i_dateObject) {
    api.listMatchesByDate(i_dateObject, function(result) {
        if (result == null || result.length < 1) {
            console.log("Game Error: Can't get games for this date - " + i_dateObject.toString());
        }
        callback(result);
    });
};

/***
 *
 * @param {Object} match_id
 */
var updateGroupMatch = function(score, match_id) {

    //Insert the sudo bet as the real score

    db.users.findOne({
        name : sudo
    }, function(err, marked) {
        if (marked.markedMatches.indexOf(match_id) > -1) {
            console.log('Points already given for this match');
        } else {
            db.users.update({
                name : sudo,
                "groups.match_id" : match_id
            }, {
                $set : {
                    "groups.$.score" : score,
                    "groups.$.marked" : false /** Guarantees that points won't be given twice! **/
                }
            }, function(err, result) {
                //Update the marked matches array
                db.users.update({
                    name : 'sudo'
                }, {
                    $push : {
                        markedMatches : match_id
                    }
                });
                //Sudo has been inserted - now can give points
                users.givePointsGroupStage(rules[0], match_id);
            });
        }
    });

};
/**
 * Write on sudo the champion, king of goals, mvp
 */
var endWorldCup = function(i_mvp, i_champion, i_kingOfGoals) {
    db.users.update({
        name : sudo
    }, {
        $set : {
            mvp : i_mvp,
            champion : i_champion,
            kingOfGoals : i_kingOfGoals
        }
    }, function(err, sudoUpdated) {
        users.givePointsTournamentBets(rules[5]);
    });
};

/***
 *exports.getAllQualifiers = getAllQualifiers;
 * @param {i_level} Level so we can decide the rules
 * @param {Object} match_id
 */
var updateKnockoutMatch = function(i_level, i_score, i_winner, match_id) {
    // var i_score = result.score;
    // var i_winner = result.winner;
    var level = rules[parseInt(i_level)];
    //Gets the level from the scheduler and finds the rules for this game
    //Insert the sudo bet after the game is over

    db.users.findOne({
        name : sudo
    }, function(err, markedMatchArr) {
        //Check if this game has been marked in the markedMatches array in sudo
        if (markedMatchArr.markedMatches.indexOf(match_id) > -1) {
            console.log('Points already given for this match');
        } else {
            //Match has not been marked

            db.users.update({
                name : sudo,
                'knockout.match_id' : match_id
            }, {
                $set : {

                    'knockout.$.score' : i_score,
                    'knockout.$.winner' : i_winner,
                    'knockout.$.marked' : false, /** This makes sure this game is only giving points once once  **/
                }

            }, function(err, sudoUpdated) {

                //Update the marked matches array
                db.users.update({
                    name : 'sudo'
                }, {
                    $push : {
                        markedMatches : match_id
                    }
                });
                //Sudo has been updated - now can give points to the users
                users.givePointsKnockout(level, match_id);

            });
        }
        //Do this only until Final
        if (i_level >= 1) {
            //Next part is to advance the winning team to the next stage, by writing to sudo and then locking the game for everyone else
            sudoAdvanceKnockoutTeam(i_winner, (i_level - 1), function(nextMatchObject) {
                if (nextMatchObject == null) {
                    //Problem!
                    console.log("Couldnt get the next match for - " + winner);
                } else {
                    //Now I know sudo has written the winning team to the next match
                    users.lockKnockoutGame(match_id/** the current match_id **/, nextMatchObject);
                }

            });
        }

    });

};

/***
 * For testing ONLY- do not use
 * @param {Object} knockoutOrGroup - true if knockout, false if group
 * @param {Object} match_id
 */
var gameOver = function(bet, level, match_id, groupName) {
    if (bet == "Knockout") {
        users.givePointsKnockout(rules[level], match_id);

    } else if (bet == "Group") {

        users.givePointsGroupStage(rules[level], match_id);

    } else {
        users.givePointsQualifiers(rules[level], groupName);
    }
};
/**
 * Called by Cron at some time after the last game of the level- writes to sudo that this level is over and that betOpen:true and bettingLevel +1
 *@param{int} this is the old level that has just ended
 */

var endBetLevel = function(i_level) {
    if (i_level != 1) {

        console.log("Ending Level " + i_level);
        var newLevel = 0;
        if (i_level == 0) {
            newLevel = 4;
        } else {
            newLevel = i_level - 1;
        }
        db.users.update({
            name : sudo
        }, {
            $set : {
                betOpen : true,
                betLevel : newLevel
            }

        });
    } else {
        //This is the end of the finals
        db.users.update({
            name : sudo
        }, {
            $set : {
                betOpen : false
            }
        });
    }
};

/**
 * Called by Cron at the start getNextStepof a new level (Epislon time before the first game of the level) - writes to sudo that this betOpen:false
 */
var startBetLevel = function() {
    db.users.update({
        name : sudo
    }, {
        $set : {
            betOpen : false
        }

    });
};

//startBetLevel();
//endBetLevel(0);

/**
 * Called by the cron only when ALL of this group level is over
 * This calls the users.endOfGroupLevel
 * @param {String} GroupName "World Cup, Group <A-H>"
 */
var updateGroupLevel = function(groupName) {

    //First check if this group has been updated already
    db.users.findOne({
        name : sudo
    }, {
        markedQualifiers : 1
    }, function(err, sudoResult) {
        if (err || !sudoResult) {
            console.log(err);
        } else {
            //Check to see if sudo has marked this group name already

            if (sudoResult.markedQualifiers.indexOf(groupName) > -1) {
                console.log("Points already given for qualifiers of group - " + groupName);
            } else {
                //Points have NOT been given for this qualifier

                api.getQualifiers(groupName, function(result) {
                    if (result == null) {
                        console.log("Error getting Qualifiers of group - " + groupName);
                    } else {
                        rankedFirst = result.rankedFirst;
                        rankedSecond = result.rankedSecond;
                        //Insert the sudo bet after the group level
                        db.users.update({
                            name : sudo,
                            'qualifiers.groupName' : groupName
                        }, {
                            $set : {
                                'qualifiers.$.rankedFirst' : rankedFirst,
                                'qualifiers.$.rankedSecond' : rankedSecond,
                                'qualifiers.$.marked' : false, /** This makes sure this game is only giving points once once  **/
                            }

                        }, function(err, sudoUpdated) {
                            //Sudo has been updated - now can give points to the users
                            users.givePointsQualifiers(rules[0], groupName);

                            //THIS NEEDS TO HAPPEN 10 SECONDS LATER
                            setTimeout(function(){
                                sudoAdvanceGroupTeams(rankedFirst, rankedSecond, function(nextMatches) {
                                if (nextMatches == null) {
                                    console.log("Error advancing the teams to the next step - " + rankedFirst + "  " + rankedSecond);
                                } else {
                                    //TODO: Is the team that was ranked first automatically home? check with @yahav
                                    //Now we can safely lock the games for all users after Sudo wrote his teams that advanced
                                    users.lockGroupGames(groupName, nextMatches);
                                }
                            });
                            },10000); 
                        });

                    }
                    //Mark this qualifier so points are not given twice
                    db.users.update({
                        name : 'sudo'
                    }, {
                        $push : {
                            markedQualifiers : groupName
                        }
                    });
                });
            }

        }
    });

};

/**
 *Private function  - advances sudo in the teamA and teamB field - takes the teams to the next game
 * Here I need to check - is the firstRanked qualifying team --> Home team in the 1/8 ??? @yahav
 * @param Team thats ranked first
 * @param Team thats ranked second
 * @param callback true when its all done
 */
var sudoAdvanceGroupTeams = function(i_rankedFirst, i_rankedSecond, callback) {
    //Advance the two teams to the next match ID
    api.getNextStep(i_rankedFirst, 4, function(firstMatch) {

        //Now a new schedule has been saved - don't need to call another!
        xmlUtils.getNextMatchByTeamName(__dirname + "/resources/schedule.xml", i_rankedSecond, 4, function(secondMatch) {

            //Write the second team to Sudo
            if (firstMatch == null || secondMatch == null) {
                console.log("Game: Couldn't get the next step for these teams" + firstMatch + " " + secondMatch);
                callback(null);
            } else {
                //This holds the two next match_ids where FirstRank and SecondRank go - we want to put them in sudo
                var nextFirstMatch_id = firstMatch.match_id;
                var nextSecondMatch_id = secondMatch.match_id;

                //Write on Sudo that the first team is going to that game
                db.users.update({
                    name : sudo,
                    'knockout.match_id' : nextFirstMatch_id
                }, {
                    $set : {
                        'knockout.$.home' : i_rankedFirst

                    }

                });

                db.users.update({
                    name : sudo,
                    'knockout.match_id' : nextSecondMatch_id
                }, {
                    $set : {
                        'knockout.$.away' : i_rankedSecond

                    }

                }, function(err, result) {
                    //Sudo has been written on (twice) so pass the matches that need to be locked for certain users
                    callback({
                        firstMatch : nextFirstMatch_id,
                        secondMatch : nextSecondMatch_id
                    });
                });

            }

        });
    });
};

/**
 *Private function  - advances sudo in the teamA and teamB field - takes the teams to the next game
 * @param Team thats ranked first
 * @param Team thats ranked second
 * @param callback true when its all done and the next match_id
 */
var sudoAdvanceKnockoutTeam = function(i_team, i_levelToGet, callback) {
    //Advance the two teams to the next match ID
    api.getNextStep(i_team, i_levelToGet, function(nextMatch) {
        //Write the team to Sudo
        if (nextMatch == null) {
            console.log("Game: Couldn't get the next step for this team - " + i_team);
            callback(null);
        } else {
            console.log("Game: " + i_team + " is playing level " + i_levelToGet + " in match - " + nextMatch.match_id);
            //This holds the two next match_ids where FirstRank and SecondRank go - we want to put them in sudo
            var nextMatch_id = nextMatch.match_id;

            if (nextMatch.home) {
                //Team is playing next match as HOME
                //Write on Sudo that the team is going to that game
                db.users.update({
                    name : sudo,
                    'knockout.match_id' : nextMatch_id
                }, {
                    $set : {
                        'knockout.$.home' : i_team
                    }

                }, function(err, result) {
                    //Sudo has been written on (twice)
                    callback({
                        id : nextMatch_id,
                        home : true
                    });
                });

            } else {
                //Team is playing next game as AWAY
                //Write on Sudo that the team is going to that game
                db.users.update({
                    name : sudo,
                    'knockout.match_id' : nextMatch_id
                }, {
                    $set : {
                        'knockout.$.away' : i_team
                    }

                }, function(err, result) {
                    //Sudo has been written on (twice)
                    callback({
                        id : nextMatch_id,
                        home : false
                    });
                });
            }

        }

    });

};

/**
 * This function gets the next teams who play in this level
 * @param level 4-1 (1 being Final)
 * @return [{match_id:<value>, home:<value> , away:<value>}]
 */
var getRealLevelTeams = function(level, callback) {

};

/**
 * Returns true if betting is allowed - false if not
 */
var isBettingAllowed = function(callback) {
    db.users.findOne({
        name : 'sudo'
    }, {
        betOpen : 1,
        betLevel : 1
    }, function(err, betStatus) {
        if (err || !betStatus) {
            console.log("app - Error finding bet status");
            callback(false);
        } else {
            callback(betStatus.betOpen);

        }
    });
};

exports.isBettingAllowed = isBettingAllowed;
exports.getRealLevelTeams = getRealLevelTeams;
exports.updateKnockoutMatch = updateKnockoutMatch;
exports.updateGroupMatch = updateGroupMatch;
exports.gameOver = gameOver;
exports.updateGroupLevel = updateGroupLevel;
exports.sudoAdvanceGroupTeams = sudoAdvanceGroupTeams;
exports.sudoAdvanceKnockoutTeam = sudoAdvanceKnockoutTeam;
exports.getMatchesByDate = getMatchesByDate;
exports.endBetLevel = endBetLevel;
exports.startBetLevel = startBetLevel;

